﻿using ProtoBuf.Message;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Yunchang;
using UI;
using System;

namespace AutoChess
{
    public class AutoChessCacheData
    {
        #region 自走棋开启前匹配信息
        private AutoChessMatchState matchState = AutoChessMatchState.FREE;
        private System.DateTime seasonEndTime = System.DateTime.MinValue;
        private System.DateTime startMatchTime = System.DateTime.MinValue;
        private int isOpen = 0;         // 是否在开启时间内  1:开启  0:关闭
        private int score = 0;
        private int grade = 0;          // 段位
 		private int rank = 0;
        private int mapId = 0;          //选中的地图
        private int weekFightCount = 0; //本周参赛场次
        private int weekRewardCoin = 0; //当前周获得的代币数量
        private bool matchPageIsOpening = false;
        private List<AutoChessRankPlayerInfo> lastSeasonRanks; //上赛季排行
        private List<AutoChessRankPlayerInfo> currentRanks;    //本赛季排行
        private AutoChessMatchSucceedPage succeedPage; // 匹配成功页面
        private long startMatchServerUTCTime = 0L;

        public AutoChessMatchState MatchState { get { return matchState; } }
        public bool IsOpen { get { return isOpen == 1; } }        // 是否在开启时间内  1:开启  0:关闭
        public System.DateTime SeasonEndTime { get { return seasonEndTime; } }
        public System.DateTime StartMatchTime { get { return startMatchTime; } }
        public int Score { get { return score; } }
        public int Grade { get { return grade; } }          // 段位
		public int Rank { get { return rank; } }   // 排行
        public int MainPageMapId { get { return mapId; } set { mapId = value; } }
        public int WeekFightCount { get { return weekFightCount; } } //本周参赛场次
        public int WeekRewardCoin { get { return weekRewardCoin; } } //当前周获得的代币数量
        public bool MatchPageIsOpening { get { return matchPageIsOpening; } set { matchPageIsOpening = value; } }
        public int DefaultShipId { set; get; }
        public long StartMatchServerTime { get { return startMatchServerUTCTime; } }

        public List<AutoChessRankPlayerInfo> LastSeasonRanks
        {
            get
            {
                if (lastSeasonRanks == null)
                {
                    lastSeasonRanks = new List<AutoChessRankPlayerInfo>();
                }
                return lastSeasonRanks;
            }
            set { lastSeasonRanks = value; }
        }
        public List<AutoChessRankPlayerInfo> CurrentRanks
        {
            get
            {
                if (currentRanks == null)
                {
                    currentRanks = new List<AutoChessRankPlayerInfo>();
                }
                return currentRanks;
            }
            set { currentRanks = value; }
        }

        #region 匹配信息处理
        // warn: 开始想不同信息刷新走不同消息的,现在是根据不同状态做不同处理就得了
        public void UpdateMatchInfo(SCAutoChessInfo info)
        {
            DefaultShipId = info.shipId;
            matchState = info.state;
            isOpen = info.isOpen;
            seasonEndTime = Yunchang.ServerTimerTool.Java2CSTimeLocale(info.seasonEndTime);
            startMatchTime = Yunchang.ServerTimerTool.Java2CSTimeLocale(info.startMatchTime);
            startMatchServerUTCTime = info.startMatchTime;
            score = info.score;
            grade = info.grade;
 			rank = info.rank;
            mapId = info.mapId;
            weekFightCount = info.weekFightCount;
            weekRewardCoin = info.weekRewardCoin;
            lastSeasonRanks = info.lastSeasonRanks;
            currentRanks = info.rankList;
            Yunchang.EventManager.TriggerEvent(CommonEvent.ON_AUTOCHESS_MATCH_INFO_UPDATE);
        }

        public void OnMatchStartInfoUpdate(SCAutoChessMatch info)
        {
            matchState = info.state;
            startMatchTime = Yunchang.ServerTimerTool.Java2CSTimeLocale(info.startMatchTime);
            startMatchServerUTCTime = info.startMatchTime;
            Yunchang.EventManager.TriggerEvent(CommonEvent.ON_AUTOCHESS_MATCH_INFO_UPDATE);

            // 匹配成功页面
            if (succeedPage != null)
            {
                succeedPage.Close();
            }
        }

        public void OnMatchSuccessInfoUpdate(SCAutoChessMatchSucess info)
        {
            matchState = info.state;

            Yunchang.EventManager.TriggerEvent(CommonEvent.ON_AUTOCHESS_MATCH_INFO_UPDATE);
            Yunchang.EventManager.TriggerEvent<long>(CommonEvent.ON_AUTOCHESS_MATCH_SUCCESS, info.enterBattleTime);

            // 匹配页面的页面历史处理
            // 当前是匹配页面，匹配成功，弹出成功页面前，需要关闭匹配页面的保存到历史记录
            AutoChessModePage modePage = PageManager.Instance.GetPage<AutoChessModePage>();
            if (modePage != null)
            {
                modePage.SaveToHistory = false;
            }
            // 在匹配页面打开其他页面，匹配页面已经在页面历史中，需要清除匹配页面的历史记录
            PageManager.Instance.RemoveHistory("AutoChessModePage");

            // 匹配成功页面
            AutoChessMatchSucceedPageParam param = new AutoChessMatchSucceedPageParam()
            {
                countDownSeconds = (ServerTimerTool.Java2CSTime(info.enterBattleTime) - ServerTimerTool.CurrentUTCTime).Seconds
            };
            PageManager.Instance.OpenPage("ChessMatchSuccessPage", param);
            succeedPage = PageManager.Instance.GetPage<AutoChessMatchSucceedPage>();
        }

        public void OnMatchCancelInfoUpdate(SCCancelAutoChessMatch info)
        {
            matchState = info.state;

            Yunchang.EventManager.TriggerEvent(CommonEvent.ON_AUTOCHESS_MATCH_INFO_UPDATE);

            // 匹配成功页面
            if (succeedPage != null)
            {
                succeedPage.Close();
            }
        }

        #endregion
        #endregion

        #region 全局信息
        private AutoChessStateType lastServerDataState = AutoChessStateType.AUTO_CHESS_STATE_WAITINT_SYNC_DATA;
        private AutoChessStateType curServerDataState = AutoChessStateType.AUTO_CHESS_STATE_WAITINT_SYNC_DATA;
        private long adjustEndTime = 0;
        private long fightEndTime = 0;
        private long matchingEndTime = 0;
        private int roundNum = 0;
        #endregion

        #region 自己的战斗信息
        private long matchingPlayer = -1;         //匹配到的玩家
        public SCAutoChessRoundFightResult fighResult;
        public SCAutoChessReconnect reconnectData;
        public SCAutoChessScoreChange overScoreData;
        private bool isGameOverOpen = false;
        public bool IsGameOverOpen
        {
            get{ return isGameOverOpen;  }
            set{ isGameOverOpen = value; }
        }
        #endregion

        private ACPlayerData curPlayerData;

        public AutoChessStateType ServerDataState { get { return curServerDataState; } }
        public long AdjustEndTime { get { return adjustEndTime; } } // 调整阶段结束时间
        public long FightEndTime { get { return fightEndTime; } }   // 战斗结束时间
        public long MatchingTime { get { return matchingEndTime; } }   // 匹配结束时间
        public int RoundNum { get { return roundNum; } }            // 当前回合数
        public long MatchingPlayer { get { return matchingPlayer; } set { matchingPlayer = value; } }
        
        /// <summary> 当前战场玩家的信息 </summary>
        public ACPlayerData CurPlayerData
        {
            get { return curPlayerData; }
        }

        public Dictionary<long, ACPlayerData> playerMap = new Dictionary<long, ACPlayerData>();

        //重置战斗场数据
        public void ResetFieldData()
        {
            lastServerDataState = curServerDataState = AutoChessStateType.AUTO_CHESS_STATE_WAITINT_SYNC_DATA;
            adjustEndTime = 0; fightEndTime = 0; matchingEndTime = 0; matchingPlayer = 0; roundNum = 0;
            playerMap.Clear();
            matchingPlayer = -1;         //匹配到的玩家
            fighResult = null;
            reconnectData = null;
            overScoreData = null;
            isGameOverOpen = false;
            ResetMatchingData();
        }

        private void ResetMatchingData()
        {
            matchState = AutoChessMatchState.FREE;
            seasonEndTime = System.DateTime.MinValue;
            startMatchTime = System.DateTime.MinValue;
            startMatchServerUTCTime = 0L;
            score = 0;
            grade = 0;
            weekFightCount = 0;
            isOpen = 0;
        }

        /* 
         * 有一种问题。 当重连进来 
         */
        public void UpdateDataAtBegin(AutoChessInfo chessInfo)
        {
            roundNum = chessInfo.roundNum;
            UpdateServerState(chessInfo.stateInfo); //更新状态信息
            for (int i = 0; i < chessInfo.playerInfos.Count; i++)
            {
                UpdatePlayerInfo(chessInfo.playerInfos[i]); //刷新所有玩家的信息
            }
        }

        #region 更新战斗状态信息

        DateTime nowTime;
        public void UpdateServerState(AutoChessStateInfo msg)
        {
            lastServerDataState = curServerDataState;
            curServerDataState = msg.stateType;

            if (lastServerDataState == AutoChessStateType.AUTO_CHESS_STATE_FIGHTING && curServerDataState == AutoChessStateType.AUTO_CHESS_STATE_ADJUST)
            {  //超时，这里超时按切换了状态 还没 退出战斗算超时
                //EventManager.TriggerEvent(CommonEvent.ON_AUTOCHESSS_FIGHT_TIMEOUT); 
            }
            switch (curServerDataState)
            {
                case AutoChessStateType.AUTO_CHESS_STATE_LOADING://收到SCBegin后 进入Loading状态。 加载场景资源 展示玩家进度条
                    { }
                    break;
                case AutoChessStateType.AUTO_CHESS_STATE_ADJUST://进入调整阶段
                    {
                        UpdateAdjustInfo(msg.adjustInfo);
                        //通知所有玩家都加载完成了，可以进入战场了.收到消息的地方自己判断是不是第一次进入
                        Yunchang.EventManager.TriggerEvent<AutoChessStateType>(CommonEvent.ON_STATE_TO_CHANGE_BY_SERVER, curServerDataState);
                        //只有初始化完了才能更具服务器直接切换
                        if (AutoChessManager.Ins.IsEnterSceneInit)
                        {
                            AutoChessManager.Ins.SwitchState(AutoChessModeState.GameFieldtate);
                        }
                    }
                    break;
                case AutoChessStateType.AUTO_CHESS_STATE_MATCHING://匹配到一个玩家
                    {
                        UpdateMatchingInfo(msg.matchingInfo);
                    }
                    break;
                case AutoChessStateType.AUTO_CHESS_STATE_FIGHTING://战斗中
                    {
                        UpdateFightingInfo(msg.fightingInfo);
                        Yunchang.EventManager.TriggerEvent<AutoChessStateType>(CommonEvent.ON_STATE_TO_CHANGE_BY_SERVER, curServerDataState);
                        Yunchang.EventManager.TriggerEvent(CommonEvent.ON_AUTOCHESS_SWITCH_BATTLE);
                    }
                    break;
                case AutoChessStateType.AUTO_CHESS_STATE_CLOSED://游戏结束
                    {
                        UpdateCloseInfo(msg.closedInfo);
                    }
                    break;
                case AutoChessStateType.AUTO_CHESS_STATE_WAITINT_SYNC_DATA:
                default:
                    break;
            }
        }

        private void UpdateCloseInfo(AutoChessStateClosedInfo closedInfo)
        {
            ////每次回到战场看是不是需要退出
            //if (AutoChessManager.Ins.GetCurrentStateType() == AutoChessModeState.GameFieldtate 
            //    || AutoChessManager.Ins.GetCurrentStateType() == AutoChessModeState.ShowFightState)
            //{
            //    AutoChessManager.Ins.ExistFightResult();
            //}
        }

        private void UpdateFightingInfo(AutoChessStateFightingInfo fightingInfo)
        {
            fightEndTime = ServerTimerTool.CurrentTime.Ticks  +  fightingInfo.endTime * 10000;
        }

        private void UpdateMatchingInfo(AutoChessStateMatchingInfo matchingInfo)
        {
            matchingEndTime = ServerTimerTool.CurrentTime.Ticks + matchingInfo.endTime * 10000;
        }

        private void UpdateAdjustInfo(AutoChessStateAdjustInfo adjustInfo)
        {
            roundNum = adjustInfo.roundNum;
            //jiava 是毫秒  C# 是纳秒
            adjustEndTime = ServerTimerTool.CurrentTime.Ticks + adjustInfo.endTime * 10000;
        }
        #endregion

        #region 更新玩家信息
        public void UpdatePlayerInfo(AutoChessPlayerInfo playerInfo)
        {
            if (playerMap.ContainsKey(playerInfo.guid))
            {
                playerMap[playerInfo.guid].UpdatePlayerInfo(playerInfo);
            }
            else
            {
                var player = new ACPlayerData();
                player.UpdatePlayerInfo(playerInfo);
                playerMap[playerInfo.guid] = player;
            }
        }
        #endregion

        #region 获取信息
        public List<ACPlayerData> GetAllPlayerList()
        {
            List<ACPlayerData> result = new List<ACPlayerData>();
            foreach (var item in playerMap)
            {
                result.Add(item.Value);
            }
            result.Sort((a, b) => { return b.HP.CompareTo(a.HP); });
            return result;
        }

        /// <summary>
        /// 切换当前玩家数据
        /// </summary>
        /// <param name="guid"></param>
        /// <returns></returns>
        public ACPlayerData SwitchFieldPlayer(long guid)
        {
            if (!playerMap.ContainsKey(guid))
            {
                Debug.LogError("玩家数据不存在：" + guid);
                return null; ;
            }
            curPlayerData = playerMap[guid];
            return playerMap[guid];
        }
        public int GetPlayerHeroFathionId(long guid,int heroId)
        {
            if (!playerMap.ContainsKey(guid))
            {
                Debug.LogError("玩家数据不存在：" + guid);
                return 0;
            }
            return playerMap[guid].GetHeroFashionId(heroId);
        }
        public ACPlayerData GetPlayerData(long guid)
        {
            if (!playerMap.ContainsKey(guid))
            {
                Debug.LogError("玩家数据不存在：" + guid);
                return null;
            }
            return playerMap[guid];
        }
        /// <summary>
        /// 获取自己的信息
        /// </summary>
        /// <returns></returns>
        public ACPlayerData GetSelfPlayerData()
        {
            return GetPlayerData(StaticData.playerData.playerId);
        }

        public ACPlayerData GetCurFieldPlayerData()
        {
            return GetPlayerData(AutoChessPlayerCtr.Ins.CurrentPlayer.playerGuid);
        }
        #endregion

        #region Parse
        /// <summary>
        /// 创建敌人
        /// </summary>
        /// <param name="matchRes">匹配信息 双方阵容</param>
        /// <param name="left"> 右边剩余的人 </param>
        /// <returns></returns>
        public ACPlayerData CreateEnemyPlayer(SCAutoChessMatchRes matchRes, List<AutoChessChessInfo> left = null)
        {
            List<AutoChessChessInfo> lefttemp = null;
            if (left != null)
            {
                lefttemp = new List<AutoChessChessInfo>();
                foreach (var item in left)
                {
                    lefttemp.Add(new AutoChessChessInfo() { chessId = item.chessId, pos = item.pos });
                }
            }

            ACPlayerData player = new ACPlayerData();
            var allHero = matchRes.right.resultChess;//野怪的还是玩家的信息
            if (matchRes.right.shipId <= 0)
            {
                player.ShipId = Table.DataModel.TableConfig.autochessDefaultShip;
            }
            else
            {
                player.ShipId = matchRes.right.shipId;
            }

            var showChess = lefttemp != null ? lefttemp : allHero; //显示剩余的还是 所有的
            foreach (var hero in showChess)
            {
                player.AddHeroData(AutoChessAreaType.AUTO_CHESS_AREA_FIGHT, hero);
            }
            return player;
        }

        #endregion 
    }
}